package com.blakebarrett.components
{
	import com.blakebarrett.model.Model;
	import com.blakebarrett.model.media.MediaInfo;
	
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.NativeDragEvent;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	
	import flexlib.containers.DragScrollingCanvas;
	
	import mx.core.ScrollPolicy;
	import mx.events.FlexEvent;
	import mx.events.ResizeEvent;
	import mx.managers.DragManager;

	[Event(name="imageLoaded", type="com.blakebarrett.events.ImageLoadedEvent")]
	public class MediaRegionBase extends DragScrollingCanvas implements IMediaRegion
	{
		public function MediaRegionBase()
		{
			clipContent = true;
			childrenDoDrag = true;
			horizontalScrollPolicy = ScrollPolicy.OFF;
			verticalScrollPolicy = ScrollPolicy.OFF;
			this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
			super();
		}
		
		[Bindable]
		protected var loaderContext : LoaderContext = new LoaderContext( true, ApplicationDomain.currentDomain );
		
		[Bindable]
		public var mediaInfo : MediaInfo = new MediaInfo();
		
		public function select() : void {
			this.drawFocus(true);
		}
		
		public function deSelect() : void {
			this.drawFocus(false);
		}
		
		/** abstract */
		public function load(url:String):void {
			throw new Error('Method is abstract. \nPlease override load( url : String ).');
		}
		
		public function get bitmapData () : BitmapData {
			var _bitmapData : BitmapData = new BitmapData( this.width, this.height );
			_bitmapData.draw( this );
			return _bitmapData;
		}
		
		/**	protected functions	*/
		protected function onCreationComplete (e:FlexEvent) : void {
			addEventListeners();
			addChangeWatchers();
		}
		
		private function onCanvasResize () : void {
			mediaInfo.regionWidth = this.width;
			mediaInfo.regionHeight = this.height;
			mediaInfo.currentXOffset = this.horizontalScrollPosition;
			mediaInfo.currentYOffset = this.verticalScrollPosition;
		}
		
		protected function onViewChanged ( e : Event ) : void {
			
			var currentHorizontalScrollPosition : Number = this.horizontalScrollPosition;
			var currentVerticalScrollPosition : Number = this.verticalScrollPosition;
			
			mediaInfo.currentXOffset = currentHorizontalScrollPosition;
			mediaInfo.currentYOffset = currentVerticalScrollPosition;
		}
		
		protected function onClick ( e : MouseEvent ) : void {
			Model.getInstance().selectedMediaInfo = this.mediaInfo;
			this.drawFocus(Model.getInstance().selectedMediaInfo == this.mediaInfo);
		}
		
		protected function addEventListeners () : void {
			this.addEventListener(ResizeEvent.RESIZE, onCanvasResize);
			this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, onNativeDragEnter);
			this.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, onNativeDragDrop);
			this.addEventListener(MouseEvent.CLICK, onClick);
			this.addEventListener("viewChanged", onViewChanged);
		}
		
		protected function removeEventListeners () : void {
			this.removeEventListener(ResizeEvent.RESIZE, onCanvasResize);
			this.removeEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, onNativeDragEnter);
			this.removeEventListener(NativeDragEvent.NATIVE_DRAG_DROP, onNativeDragDrop);
			this.removeEventListener(MouseEvent.CLICK, onClick);
			this.removeEventListener("viewChanged", onViewChanged);
		}
		
		protected function addChangeWatchers () : void {
			
		}
		
		protected function removeChangeWatchers() : void {
			
		}
		
		/** abstract */
		protected function onMediaUpdateComplete ( e : Event ) : void {
			throw new Error('Method is abstract. \nPlease override onMediaUpdateComplete( e : Event).');
		}
		
		/** private functions */
		private function onNativeDragEnter ( e : NativeDragEvent ) : void {
			DragManager.acceptDragDrop( this );
		}
		
		protected function onNativeDragDrop ( e : NativeDragEvent ) : void {
			mediaInfo.source = e.clipboard.getData("air:url").toString();
		}
	}
}